/*
 * CutStackFilter.java
 *
 * Created on December 1, 2008
 * Written by Eran Gilon
 * 
 * This filter will imposition N-up Cut and Stack
 *   the user can select the number of pages across (columns)
 *   and pages down (rows) on the sheet
 */

package net.anzix.jimposition.transformations;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.swing.JPanel;
import net.anzix.jimposition.BasicTransformation;

public class CutStackFilter extends BasicTransformation {

	private CutStackFilterPanel panel = new CutStackFilterPanel();


	public byte[] alter(byte[] input) {
		try {
             
			PdfReader inputReader = new PdfReader(input);
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			Rectangle pageSize = inputReader.getPageSize(1);
			int rows = Integer.parseInt((String) getAttribute("rows"));
			int columns = Integer.parseInt((String) getAttribute("columns"));
			rows = (rows < 1) ? 1 : rows;
			columns = (columns < 1) ? 1 : columns;
			int stacks = rows * columns;
			Document document = new Document(new Rectangle(pageSize.right()*columns,pageSize.top()*rows));
			PdfWriter writer = PdfWriter.getInstance(document, outputStream);
			document.open();

			int pages = inputReader.getNumberOfPages();
			PdfContentByte cb = writer.getDirectContent();
			Integer numSheets = (pages- 1) / stacks + 1;

			for (Integer thisSheet = 1; thisSheet <= numSheets; thisSheet = ++thisSheet) { //loop sheets
				document.newPage();
				for (Integer thisRow = 1; thisRow <= rows; thisRow = ++thisRow ) { //loop rows
					for (Integer thisColumn = 1; thisColumn <= columns; thisColumn = ++thisColumn ) { //loop columns
						Integer thisStack = ((thisRow-1) * columns)+ thisColumn;
						Integer thisPage = thisSheet + (thisStack - 1) * numSheets;
						float offsetx=pageSize.right()* (thisColumn-1);
						//float offsety=pageSize.getTop()* (thisColumn-1);
						float offsety=pageSize.top()* (rows - thisRow);

						if (thisPage <= pages) { // add a page to the sheet
							cb.addTemplate(writer.getImportedPage(inputReader, thisPage ),1f,0f,0f,1f,offsetx,offsety);
							cb.stroke();
						} // if - add page
					} // loop columns
				} // loop rows
			} // loop sheets

			document.close();
			return outputStream.toByteArray();
		} catch (DocumentException ex) {
			ex.printStackTrace();
			return null;
		} catch (IOException ex) {
			ex.printStackTrace();
			return null;
		}

	}

	public String toString() {
		return "Imposition Cut and Stack";
	}

	public void setPanelSettings() {

		//        panel.getNumRows().setText(getAttribute("rows").toString());
		//        panel.getNumColumns().setText(getAttribute("columns").toString());
	}

	public void getPanelSettings() {
		setAttribute("rows", panel.getNumRows().getText());
		setAttribute("columns", panel.getNumColumns().getText());
	}

	public JPanel getPanel() {
		return panel;
	}
}
